package com.mrxu.monitor.service;

import cn.hutool.core.util.ObjectUtil;
import com.mrxu.monitor.bean.IpRegion;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class IpService {

    private static Searcher searcher;

    /**
     * 判断是否为合法 IP
     * @return
     */
    private boolean checkIp(String ipAddress) {
        String ip = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
        Pattern pattern = Pattern.compile(ip);
        Matcher matcher = pattern.matcher(ipAddress);
        return matcher.matches();
    }

    /**
     * 在服务启动时，将 ip2region 加载到内存中
     */
    @PostConstruct
    private void initIp2Region() {
        try {
            InputStream inputStream = new ClassPathResource("/ip2region.xdb").getInputStream();
            byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
            searcher = Searcher.newWithBuffer(bytes);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 返回region信息国家、省份、区域
     * @param ip
     * @return
     */
    public IpRegion getRegionInfo(String ip) {
        IpRegion result = new IpRegion();
        //特殊ip直接返回
        if("0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)
                || "127.0.0.1".equalsIgnoreCase(ip)
                || "localhost".equalsIgnoreCase(ip)){
            result.setLocalIp(true);
            return result;
        }
        if (!checkIp(ip)) {
            result.setUnkown(true);
            return result;
        }
        try {
            // searchIpInfo 的数据格式： 国家|区域|省份|城市|ISP
            String searchIpInfo = searcher.search(ip);
            if(ObjectUtil.isNotEmpty(searchIpInfo)) {
                searchIpInfo = searchIpInfo.replaceAll("市","");
            }
            String[] splitIpInfo = searchIpInfo.split("\\|");
            if (splitIpInfo.length > 0) {
                if ("0".equals(splitIpInfo[0])) {
                    if ("内网IP".equals(splitIpInfo[4])) {
                        // 内网 IP
                        result.setLocalIp(true);
                        return result;
                    } else {
                        result.setUnkown(true);
                        return result;
                    }
                } else if("中国".equals(splitIpInfo[0])){
                    // 国外属地返回国家
                    result.setCountry(splitIpInfo[0]);
                    result.setProvince(splitIpInfo[2]);
                    result.setCity(splitIpInfo[3]);
                    result.setChina(true);
                    return result;
                }else {
                    result.setCountry(splitIpInfo[0]);
                    // 国外属地返回国家
                    return result;
                }
            }
            else {
                result.setUnkown(true);
                return result;
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.setUnkown(true);
            return result;
        }
    }

    /**
     * 获取 ip 所属地址
     *
     * @param ip ip
     * @return
     */
    public String getIpRegion(String ip) {
        boolean isIp = checkIp(ip);
        if (isIp) {
            try {
                // searchIpInfo 的数据格式： 国家|区域|省份|城市|ISP
                String searchIpInfo = searcher.search(ip);
                System.out.println("ip 信息："+searchIpInfo);
                String[] splitIpInfo = searchIpInfo.split("\\|");
                if (splitIpInfo.length > 0) {
                    if ("中国".equals(splitIpInfo[0])) {
                        // 国内属地返回省份
                        return splitIpInfo[2] + "|" + splitIpInfo[3];
                    } else if ("0".equals(splitIpInfo[0])) {
                        if ("内网IP".equals(splitIpInfo[4])) {
                            // 内网 IP
                            return splitIpInfo[4];
                        } else {
                            return "";
                        }
                    } else {
                        // 国外属地返回国家
                        return splitIpInfo[0];
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
        else {
            throw new IllegalArgumentException("非法的IP地址");
        }
    }

    public static void main(String[] args) {
        IpService test = new IpService();
        test.initIp2Region();
        System.out.println(test.getRegionInfo("117.152.94.141"));
        System.out.println(test.getRegionInfo("67.220.90.13"));
    }

}
